<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>浅拷贝和深拷贝</title>
</head>

<body>

</body>
<script>
  // 基本数据类型：按值来传递
  var a = 1;
  var b = a;
  b = 200;
  // console.log(b); //200
  // console.log(a); //1

  // 引用数据类型：按引用地址来传递
  var arr = [1, 2, 3];
  var newArr = arr;
  newArr.push(10);
  // console.log(newArr);  // [1,2,3,10]
  // console.log(arr);  // [1,2,3,10]

  // 拷贝：浅拷贝 和 深拷贝
  // 操作拷贝之后的对象的某个属性不会影响原始对象中的属性，这种拷贝称为深拷贝，反之，有影响叫浅拷贝
  var obj = {
    name: '张三',
    age: 20,
    hobby: ['炸金花', '搓麻将', '推牌九'],
    friend: {
      name: '李四',
      age: 20,
      hobby: '搓麻将',
      friend: {
        name: '王五',
        age: 22,
        hobby: '推牌九',
      }
    }
  }

  // 实现浅拷贝
  function shadowCopy(toObj, fromObj) {
    for (var key in fromObj) {
      toObj[key] = fromObj[key];
    }
    return toObj;
  }
  // 浅拷贝不是直接赋值，浅拷贝新建了一个对象，将原来对象的属性都一一的复制过来，复制的是值，而不是引用，浅拷贝的复制只复制了第一层的属性
  // 并没有递归所有的值复制过来
  var newObj = shadowCopy({}, obj);
  newObj.age = 30;
  newObj.friend.name = '王麻子';
  console.log('newObj:', newObj);
  console.log('obj:', obj);

  // 深拷贝对目标对象的完全拷贝，不像浅拷贝那样只是复制了一层引用，就连值也复制过来，只要进行了深拷贝，就谁也不影响谁
  function deepCopy(toObj, fromObj) {
    // 遍历fromObj对象的所有属性，拷贝到toObj对象中
    for (var key in fromObj) {
      // 不遍历原型链上的属性
      if (fromObj.hasOwnProperty(key)) {
        // 如果值是对象并且有值，再遍历对象
        if (fromObj[key] && typeof fromObj[key] === 'object') {
          // 区分是一般对象还是数组
          toObj[key] = fromObj[key].constructor === Array ? [] : {};
          toObj[key] = deepCopy(toObj[key], fromObj[key]);
        } else {
          // 如果不是直接赋值
          toObj[key] = fromObj[key];
        }
      }
    }
    return toObj;
  }
  var newObj = deepCopy({}, obj);
  newObj.friend.name = '张麻子';
  console.log(newObj);
  console.log(obj);







</script>

</html>